﻿Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Runtime.Serialization
Imports System.Xml.Serialization
Imports CQRSAzure.Tools

''' <summary>
''' Class to describe a projection for code generation purposes
''' </summary>
''' <remarks>
''' Each projection must have an unique name
''' </remarks>
<Serializable>
<DataContract(Name:=NameOf(ProjectionModel))>
Public NotInheritable Class ProjectionModel
    Implements INotifyPropertyChanged
    Implements IEquatable(Of ProjectionModel)

    <DataMember(Name:=NameOf(Name))>
    Private ReadOnly m_name As String
    ''' <summary>
    ''' The unique name by which the projection is known
    ''' </summary>
    <XmlAttribute(AttributeName:="ProjectionName")>
    Public ReadOnly Property Name As String
        Get
            Return m_name
        End Get
    End Property

    Private m_eventsHandled As New Dictionary(Of String, EventHandledModel)
    ''' <summary>
    ''' The set of events handled by this projection
    ''' </summary>
    ''' <remarks>
    ''' This covers both the event typoe and also what is done with the event
    ''' </remarks>
    Public ReadOnly Property EventsHandled As Dictionary(Of String, EventHandledModel)
        Get
            Return m_eventsHandled
        End Get
    End Property


    Property m_properties As New Dictionary(Of String, Type)
    ''' <summary>
    ''' The set of intrinsic properties of this projection
    ''' </summary>
    ''' <remarks>
    ''' These a re conceptially similar to columns in a data table - they represent the state
    ''' of the projection at any given time
    ''' </remarks>
    Public ReadOnly Property Properties As Dictionary(Of String, Type)
        Get
            Return m_properties
        End Get
    End Property

#Region "Serialisation"

    Public Sub GetObjectData(info As SerializationInfo, context As StreamingContext)
        If (info IsNot Nothing) Then
            info.AddValue(NameOf(Name), m_name)
        End If
    End Sub

#End Region

#Region "Property Change Notification"
    Public Sub OnPropertyChanged(ByVal propertyName As String)

        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))

    End Sub
    Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
#End Region


#Region "Equality"

    Public Overrides Function Equals(obj As Object) As Boolean

        If (TypeOf (obj) Is ProjectionModel) Then
            Return EqualsProjectionModel(obj)
        Else
            Return False
        End If

    End Function

    Public Overloads Function EqualsProjectionModel(other As ProjectionModel) As Boolean Implements IEquatable(Of ProjectionModel).Equals

        If (other IsNot Nothing) Then
            Return m_name.Equals(other.Name)
        Else
            Return False
        End If

    End Function

#End Region

#Region "Public constructors"
    ''' <summary>
    ''' Empty constructor for serialisation
    ''' </summary>
    Public Sub New()

    End Sub

    Public Sub New(ByVal InitialProjectionName As String)
        m_name = InitialProjectionName
    End Sub

    Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext)
        If (info IsNot Nothing) Then
            m_name = info.GetString(NameOf(Name))
        End If
    End Sub

#End Region
End Class
